1 module directx.d2d1helper; 2 /*=========================================================================*\ 3 4 Copyright (c) Microsoft Corporation. All rights reserved. 5 6 File: D2D1helper.h 7 8 Module Name: D2D 9 10 Description: Helper files over the D2D interfaces and APIs. 11 12 \*=========================================================================*/ 13 14 version(Windows): 15 16 version(Direct2D_1_3) 17 version = Direct2D_1_2; 18 version(Direct2D_1_2) 19 version = Direct2D_1_1; 20 version(Direct2D_1_1): 21 version = Direct2D_1_0; 22 23 version(DirectWrite): 24 version(WinCodec): 25 version(Direct2D_1_0): 26 27 public import directx.d2d1; 28 29 struct D2D1 30 { 31 // 32 // The default trait type for objects in D2D is float. 33 // 34 template TypeTraits(T) 35 { 36 alias Point = D2D1_POINT_2F; 37 alias Size = D2D1_SIZE_F; 38 alias Rect = D2D1_RECT_F; 39 } 40 41 template TypeTraits(T : UINT32) 42 { 43 alias Point = D2D1_POINT_2U; 44 alias Size = D2D1_SIZE_U; 45 alias Rect = D2D1_RECT_U; 46 } 47 48 static nothrow 49 FLOAT FloatMax() 50 { 51 static if ( __traits(compiles, FLT_MAX.stringof) ) 52 return FLT_MAX; 53 else 54 return 3.402823466e+38F; 55 } 56 57 // 58 // Construction helpers 59 // 60 61 template Point2(Type) 62 { 63 struct Point2_(Type) 64 { 65 Type x; 66 Type y; 67 } 68 69 static Point2_!Type Point2(Type x, Type y) 70 { 71 72 return Point2_(x,y); 73 } 74 } 75 76 77 static D2D1_POINT_2F 78 Point2F( 79 FLOAT x = 0.0f, 80 FLOAT y = 0.0f 81 ) 82 { 83 return D2D1_POINT_2F(x, y); 84 } 85 86 static D2D1_POINT_2U 87 Point2U( 88 UINT32 x = 0, 89 UINT32 y = 0 90 ) 91 { 92 return D2D1_POINT_2U(x, y); 93 } 94 95 template Size(Type) 96 { 97 static TypeTraits!Type.Size Size( Type width, Type height ) 98 { 99 TypeTraits!Type.Size size = { width, height }; 100 return size; 101 } 102 } 103 104 static D2D1_SIZE_F SizeF( FLOAT width = 0.0f, FLOAT height = 0.0f ) 105 { 106 return Size!FLOAT(width, height); 107 } 108 109 static D2D1_SIZE_U SizeU( UINT32 width = 0, UINT32 height = 0 ) 110 { 111 return Size!UINT32(width, height); 112 } 113 114 115 template Rect(Type) 116 { 117 static TypeTraits!Type.Rect Rect( 118 Type left, 119 Type top, 120 Type right, 121 Type bottom 122 ) 123 { 124 TypeTraits!Type.Rect rect = { left, top, right, bottom }; 125 return rect; 126 } 127 } 128 129 static D2D1_RECT_F RectF( 130 FLOAT left = 0.0f, 131 FLOAT top = 0.0f, 132 FLOAT right = 0.0f, 133 FLOAT bottom = 0.0f 134 ) 135 { 136 return Rect!FLOAT(left, top, right, bottom); 137 } 138 139 static D2D1_RECT_U RectU( 140 UINT32 left = 0, 141 UINT32 top = 0, 142 UINT32 right = 0, 143 UINT32 bottom = 0 144 ) 145 { 146 return Rect!UINT32(left, top, right, bottom); 147 } 148 149 static D2D1_RECT_F 150 InfiniteRect() 151 { 152 D2D1_RECT_F rect = { -FloatMax(), -FloatMax(), FloatMax(), FloatMax() }; 153 return rect; 154 } 155 156 static D2D1_ARC_SEGMENT 157 ArcSegment( 158 const(D2D1_POINT_2F) point, 159 const(D2D1_SIZE_F) size, 160 FLOAT rotationAngle, 161 const(D2D1_SWEEP_DIRECTION) sweepDirection, 162 const(D2D1_ARC_SIZE) arcSize 163 ) 164 { 165 D2D1_ARC_SEGMENT arcSegment = { point, size, rotationAngle, sweepDirection, arcSize }; 166 167 return arcSegment; 168 } 169 170 171 static D2D1_BEZIER_SEGMENT 172 BezierSegment( 173 const(D2D1_POINT_2F) point1, 174 const(D2D1_POINT_2F) point2, 175 const(D2D1_POINT_2F) point3 176 ) 177 { 178 D2D1_BEZIER_SEGMENT bezierSegment = { point1, point2, point3 }; 179 180 return bezierSegment; 181 } 182 183 static D2D1_ELLIPSE 184 Ellipse( 185 in D2D1_POINT_2F center, 186 FLOAT radiusX, 187 FLOAT radiusY 188 ) 189 { 190 D2D1_ELLIPSE ellipse; 191 192 ellipse.point = center; 193 ellipse.radiusX = radiusX; 194 ellipse.radiusY = radiusY; 195 196 return ellipse; 197 } 198 199 static D2D1_ROUNDED_RECT 200 RoundedRect( 201 in D2D1_RECT_F rect, 202 FLOAT radiusX, 203 FLOAT radiusY 204 ) 205 { 206 D2D1_ROUNDED_RECT roundedRect; 207 208 roundedRect.rect = rect; 209 roundedRect.radiusX = radiusX; 210 roundedRect.radiusY = radiusY; 211 212 return roundedRect; 213 } 214 215 static D2D1_BRUSH_PROPERTIES 216 BrushProperties( 217 FLOAT opacity = 1.0, 218 in D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix() 219 ) 220 { 221 D2D1_BRUSH_PROPERTIES brushProperties; 222 223 brushProperties.opacity = opacity; 224 brushProperties.transform = transform; 225 226 return brushProperties; 227 } 228 229 static D2D1_GRADIENT_STOP 230 GradientStop( 231 FLOAT position, 232 in D2D1_COLOR_F color 233 ) 234 { 235 D2D1_GRADIENT_STOP gradientStop = { position, color }; 236 237 return gradientStop; 238 } 239 240 static D2D1_QUADRATIC_BEZIER_SEGMENT 241 QuadraticBezierSegment( 242 in D2D1_POINT_2F point1, 243 in D2D1_POINT_2F point2 244 ) 245 { 246 D2D1_QUADRATIC_BEZIER_SEGMENT quadraticBezier = { point1, point2 }; 247 248 return quadraticBezier; 249 } 250 251 static D2D1_STROKE_STYLE_PROPERTIES 252 StrokeStyleProperties( 253 D2D1_CAP_STYLE startCap = D2D1_CAP_STYLE_FLAT, 254 D2D1_CAP_STYLE endCap = D2D1_CAP_STYLE_FLAT, 255 D2D1_CAP_STYLE dashCap = D2D1_CAP_STYLE_FLAT, 256 D2D1_LINE_JOIN lineJoin = D2D1_LINE_JOIN_MITER, 257 FLOAT miterLimit = 10.0f, 258 D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID, 259 FLOAT dashOffset = 0.0f 260 ) 261 { 262 D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties; 263 264 strokeStyleProperties.startCap = startCap; 265 strokeStyleProperties.endCap = endCap; 266 strokeStyleProperties.dashCap = dashCap; 267 strokeStyleProperties.lineJoin = lineJoin; 268 strokeStyleProperties.miterLimit = miterLimit; 269 strokeStyleProperties.dashStyle = dashStyle; 270 strokeStyleProperties.dashOffset = dashOffset; 271 272 return strokeStyleProperties; 273 } 274 275 static D2D1_BITMAP_BRUSH_PROPERTIES 276 BitmapBrushProperties( 277 D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP, 278 D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP, 279 D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR 280 ) 281 { 282 D2D1_BITMAP_BRUSH_PROPERTIES bitmapBrushProperties; 283 284 bitmapBrushProperties.extendModeX = extendModeX; 285 bitmapBrushProperties.extendModeY = extendModeY; 286 bitmapBrushProperties.interpolationMode = interpolationMode; 287 288 return bitmapBrushProperties; 289 } 290 291 static D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES 292 LinearGradientBrushProperties( 293 in D2D1_POINT_2F startPoint, 294 in D2D1_POINT_2F endPoint 295 ) 296 { 297 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties; 298 299 linearGradientBrushProperties.startPoint = startPoint; 300 linearGradientBrushProperties.endPoint = endPoint; 301 302 return linearGradientBrushProperties; 303 } 304 305 static D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES 306 RadialGradientBrushProperties( 307 in D2D1_POINT_2F center, 308 in D2D1_POINT_2F gradientOriginOffset, 309 FLOAT radiusX, 310 FLOAT radiusY 311 ) 312 { 313 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties; 314 315 radialGradientBrushProperties.center = center; 316 radialGradientBrushProperties.gradientOriginOffset = gradientOriginOffset; 317 radialGradientBrushProperties.radiusX = radiusX; 318 radialGradientBrushProperties.radiusY = radiusY; 319 320 return radialGradientBrushProperties; 321 } 322 323 // 324 // PixelFormat 325 // 326 static D2D1_PIXEL_FORMAT 327 PixelFormat( 328 in DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN, 329 in D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_UNKNOWN 330 ) 331 { 332 D2D1_PIXEL_FORMAT pixelFormat; 333 334 pixelFormat.format = dxgiFormat; 335 pixelFormat.alphaMode = alphaMode; 336 337 return pixelFormat; 338 } 339 340 // 341 // Bitmaps 342 // 343 static D2D1_BITMAP_PROPERTIES 344 BitmapProperties( 345 in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 346 FLOAT dpiX = 96.0f, 347 FLOAT dpiY = 96.0f 348 ) 349 { 350 D2D1_BITMAP_PROPERTIES bitmapProperties; 351 352 bitmapProperties.pixelFormat = pixelFormat; 353 bitmapProperties.dpiX = dpiX; 354 bitmapProperties.dpiY = dpiY; 355 356 return bitmapProperties; 357 } 358 359 360 // 361 // Render Targets 362 // 363 static D2D1_RENDER_TARGET_PROPERTIES 364 RenderTargetProperties( 365 D2D1_RENDER_TARGET_TYPE type = D2D1_RENDER_TARGET_TYPE_DEFAULT, 366 in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 367 FLOAT dpiX = 0.0, 368 FLOAT dpiY = 0.0, 369 D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE, 370 D2D1_FEATURE_LEVEL minLevel = D2D1_FEATURE_LEVEL_DEFAULT 371 ) 372 { 373 D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties; 374 375 renderTargetProperties.type = type; 376 renderTargetProperties.pixelFormat = pixelFormat; 377 renderTargetProperties.dpiX = dpiX; 378 renderTargetProperties.dpiY = dpiY; 379 renderTargetProperties.usage = usage; 380 renderTargetProperties.minLevel = minLevel; 381 382 return renderTargetProperties; 383 } 384 385 static D2D1_RENDER_TARGET_PROPERTIES* 386 RenderTargetPropertiesPtr( 387 D2D1_RENDER_TARGET_TYPE type = D2D1_RENDER_TARGET_TYPE_DEFAULT, 388 in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 389 FLOAT dpiX = 0.0, 390 FLOAT dpiY = 0.0, 391 D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE, 392 D2D1_FEATURE_LEVEL minLevel = D2D1_FEATURE_LEVEL_DEFAULT 393 ) 394 { 395 D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties = new D2D1_RENDER_TARGET_PROPERTIES(); 396 397 renderTargetProperties.type = type; 398 renderTargetProperties.pixelFormat = pixelFormat; 399 renderTargetProperties.dpiX = dpiX; 400 renderTargetProperties.dpiY = dpiY; 401 renderTargetProperties.usage = usage; 402 renderTargetProperties.minLevel = minLevel; 403 404 return renderTargetProperties; 405 } 406 407 static D2D1_HWND_RENDER_TARGET_PROPERTIES 408 HwndRenderTargetProperties( 409 HWND hwnd, 410 in D2D1_SIZE_U pixelSize = D2D1.Size(cast(UINT32)0, cast(UINT32)0), 411 in D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE 412 ) 413 { 414 D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderTargetProperties; 415 416 hwndRenderTargetProperties.hwnd = hwnd; 417 hwndRenderTargetProperties.pixelSize = pixelSize; 418 hwndRenderTargetProperties.presentOptions = presentOptions; 419 420 return hwndRenderTargetProperties; 421 } 422 423 static D2D1_HWND_RENDER_TARGET_PROPERTIES* 424 HwndRenderTargetPropertiesPtr( 425 HWND hwnd, 426 in D2D1_SIZE_U pixelSize = D2D1.Size(cast(UINT32)0, cast(UINT32)0), 427 in D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE 428 ) 429 { 430 D2D1_HWND_RENDER_TARGET_PROPERTIES* hwndRenderTargetProperties = new D2D1_HWND_RENDER_TARGET_PROPERTIES(); 431 432 hwndRenderTargetProperties.hwnd = hwnd; 433 hwndRenderTargetProperties.pixelSize = pixelSize; 434 hwndRenderTargetProperties.presentOptions = presentOptions; 435 436 return hwndRenderTargetProperties; 437 } 438 439 static D2D1_LAYER_PARAMETERS 440 LayerParameters( 441 in D2D1_RECT_F contentBounds = D2D1.InfiniteRect(), 442 ID2D1Geometry geometricMask = null, 443 D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, 444 D2D1_MATRIX_3X2_F maskTransform = D2D1.IdentityMatrix(), 445 FLOAT opacity = 1.0, 446 ID2D1Brush opacityBrush = null, 447 D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE 448 ) 449 { 450 D2D1_LAYER_PARAMETERS layerParameters; 451 452 layerParameters.contentBounds = contentBounds; 453 layerParameters.geometricMask = geometricMask; 454 layerParameters.maskAntialiasMode = maskAntialiasMode; 455 layerParameters.maskTransform = maskTransform; 456 layerParameters.opacity = opacity; 457 layerParameters.opacityBrush = opacityBrush; 458 layerParameters.layerOptions = layerOptions; 459 460 return layerParameters; 461 } 462 463 static D2D1_DRAWING_STATE_DESCRIPTION 464 DrawingStateDescription( 465 D2D1_ANTIALIAS_MODE antialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, 466 D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, 467 D2D1_TAG tag1 = 0, 468 D2D1_TAG tag2 = 0, 469 in D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix() 470 ) 471 { 472 D2D1_DRAWING_STATE_DESCRIPTION drawingStateDescription; 473 474 drawingStateDescription.antialiasMode = antialiasMode; 475 drawingStateDescription.textAntialiasMode = textAntialiasMode; 476 drawingStateDescription.tag1 = tag1; 477 drawingStateDescription.tag2 = tag2; 478 drawingStateDescription.transform = transform; 479 480 return drawingStateDescription; 481 } 482 483 // 484 // Colors, this enum defines a set of predefined colors. 485 // 486 struct ColorF 487 { 488 public: 489 D2D1_COLOR_F color; 490 alias color this; 491 492 alias Enum = uint; 493 enum : Enum 494 { 495 AliceBlue = 0xF0F8FF, 496 AntiqueWhite = 0xFAEBD7, 497 Aqua = 0x00FFFF, 498 Aquamarine = 0x7FFFD4, 499 Azure = 0xF0FFFF, 500 Beige = 0xF5F5DC, 501 Bisque = 0xFFE4C4, 502 Black = 0x000000, 503 BlanchedAlmond = 0xFFEBCD, 504 Blue = 0x0000FF, 505 BlueViolet = 0x8A2BE2, 506 Brown = 0xA52A2A, 507 BurlyWood = 0xDEB887, 508 CadetBlue = 0x5F9EA0, 509 Chartreuse = 0x7FFF00, 510 Chocolate = 0xD2691E, 511 Coral = 0xFF7F50, 512 CornflowerBlue = 0x6495ED, 513 Cornsilk = 0xFFF8DC, 514 Crimson = 0xDC143C, 515 Cyan = 0x00FFFF, 516 DarkBlue = 0x00008B, 517 DarkCyan = 0x008B8B, 518 DarkGoldenrod = 0xB8860B, 519 DarkGray = 0xA9A9A9, 520 DarkGreen = 0x006400, 521 DarkKhaki = 0xBDB76B, 522 DarkMagenta = 0x8B008B, 523 DarkOliveGreen = 0x556B2F, 524 DarkOrange = 0xFF8C00, 525 DarkOrchid = 0x9932CC, 526 DarkRed = 0x8B0000, 527 DarkSalmon = 0xE9967A, 528 DarkSeaGreen = 0x8FBC8F, 529 DarkSlateBlue = 0x483D8B, 530 DarkSlateGray = 0x2F4F4F, 531 DarkTurquoise = 0x00CED1, 532 DarkViolet = 0x9400D3, 533 DeepPink = 0xFF1493, 534 DeepSkyBlue = 0x00BFFF, 535 DimGray = 0x696969, 536 DodgerBlue = 0x1E90FF, 537 Firebrick = 0xB22222, 538 FloralWhite = 0xFFFAF0, 539 ForestGreen = 0x228B22, 540 Fuchsia = 0xFF00FF, 541 Gainsboro = 0xDCDCDC, 542 GhostWhite = 0xF8F8FF, 543 Gold = 0xFFD700, 544 Goldenrod = 0xDAA520, 545 Gray = 0x808080, 546 Green = 0x008000, 547 GreenYellow = 0xADFF2F, 548 Honeydew = 0xF0FFF0, 549 HotPink = 0xFF69B4, 550 IndianRed = 0xCD5C5C, 551 Indigo = 0x4B0082, 552 Ivory = 0xFFFFF0, 553 Khaki = 0xF0E68C, 554 Lavender = 0xE6E6FA, 555 LavenderBlush = 0xFFF0F5, 556 LawnGreen = 0x7CFC00, 557 LemonChiffon = 0xFFFACD, 558 LightBlue = 0xADD8E6, 559 LightCoral = 0xF08080, 560 LightCyan = 0xE0FFFF, 561 LightGoldenrodYellow = 0xFAFAD2, 562 LightGreen = 0x90EE90, 563 LightGray = 0xD3D3D3, 564 LightPink = 0xFFB6C1, 565 LightSalmon = 0xFFA07A, 566 LightSeaGreen = 0x20B2AA, 567 LightSkyBlue = 0x87CEFA, 568 LightSlateGray = 0x778899, 569 LightSteelBlue = 0xB0C4DE, 570 LightYellow = 0xFFFFE0, 571 Lime = 0x00FF00, 572 LimeGreen = 0x32CD32, 573 Linen = 0xFAF0E6, 574 Magenta = 0xFF00FF, 575 Maroon = 0x800000, 576 MediumAquamarine = 0x66CDAA, 577 MediumBlue = 0x0000CD, 578 MediumOrchid = 0xBA55D3, 579 MediumPurple = 0x9370DB, 580 MediumSeaGreen = 0x3CB371, 581 MediumSlateBlue = 0x7B68EE, 582 MediumSpringGreen = 0x00FA9A, 583 MediumTurquoise = 0x48D1CC, 584 MediumVioletRed = 0xC71585, 585 MidnightBlue = 0x191970, 586 MintCream = 0xF5FFFA, 587 MistyRose = 0xFFE4E1, 588 Moccasin = 0xFFE4B5, 589 NavajoWhite = 0xFFDEAD, 590 Navy = 0x000080, 591 OldLace = 0xFDF5E6, 592 Olive = 0x808000, 593 OliveDrab = 0x6B8E23, 594 Orange = 0xFFA500, 595 OrangeRed = 0xFF4500, 596 Orchid = 0xDA70D6, 597 PaleGoldenrod = 0xEEE8AA, 598 PaleGreen = 0x98FB98, 599 PaleTurquoise = 0xAFEEEE, 600 PaleVioletRed = 0xDB7093, 601 PapayaWhip = 0xFFEFD5, 602 PeachPuff = 0xFFDAB9, 603 Peru = 0xCD853F, 604 Pink = 0xFFC0CB, 605 Plum = 0xDDA0DD, 606 PowderBlue = 0xB0E0E6, 607 Purple = 0x800080, 608 Red = 0xFF0000, 609 RosyBrown = 0xBC8F8F, 610 RoyalBlue = 0x4169E1, 611 SaddleBrown = 0x8B4513, 612 Salmon = 0xFA8072, 613 SandyBrown = 0xF4A460, 614 SeaGreen = 0x2E8B57, 615 SeaShell = 0xFFF5EE, 616 Sienna = 0xA0522D, 617 Silver = 0xC0C0C0, 618 SkyBlue = 0x87CEEB, 619 SlateBlue = 0x6A5ACD, 620 SlateGray = 0x708090, 621 Snow = 0xFFFAFA, 622 SpringGreen = 0x00FF7F, 623 SteelBlue = 0x4682B4, 624 Tan = 0xD2B48C, 625 Teal = 0x008080, 626 Thistle = 0xD8BFD8, 627 Tomato = 0xFF6347, 628 Turquoise = 0x40E0D0, 629 Violet = 0xEE82EE, 630 Wheat = 0xF5DEB3, 631 White = 0xFFFFFF, 632 WhiteSmoke = 0xF5F5F5, 633 Yellow = 0xFFFF00, 634 YellowGreen = 0x9ACD32, 635 } 636 637 638 // 639 // Construct a color, note that the alpha value from the "rgb" component 640 // is never used. 641 // 642 this( 643 UINT32 rgb, 644 FLOAT a = 1.0 645 ) 646 { 647 Init(rgb, a); 648 } 649 /* 650 this( 651 Enum knownColor, 652 FLOAT a = 1.0 653 ) 654 { 655 Init(knownColor, a); 656 } 657 */ 658 659 this( 660 FLOAT r, 661 FLOAT g, 662 FLOAT b, 663 FLOAT a = 1.0 664 ) 665 { 666 this.r = r; 667 this.g = g; 668 this.b = b; 669 this.a = a; 670 } 671 672 private: 673 674 void 675 Init( 676 UINT32 rgb, 677 FLOAT a 678 ) 679 { 680 this.r = cast(FLOAT)((rgb & sc_redMask) >> sc_redShift) / 255.0f; 681 this.g = cast(FLOAT)((rgb & sc_greenMask) >> sc_greenShift) / 255.0f; 682 this.b = cast(FLOAT)((rgb & sc_blueMask) >> sc_blueShift) / 255.0f; 683 this.a = a; 684 } 685 686 static const UINT32 sc_redShift = 16; 687 static const UINT32 sc_greenShift = 8; 688 static const UINT32 sc_blueShift = 0; 689 690 static const UINT32 sc_redMask = 0xff << sc_redShift; 691 static const UINT32 sc_greenMask = 0xff << sc_greenShift; 692 static const UINT32 sc_blueMask = 0xff << sc_blueShift; 693 } 694 695 696 struct Matrix3x2F //: public D2D1_MATRIX_3X2_F 697 { 698 public: 699 D2D1_MATRIX_3X2_F matrix; 700 alias matrix this; 701 702 this(D2D1_MATRIX_3X2_F m) 703 { 704 matrix = m; 705 } 706 707 this( 708 FLOAT _11, 709 FLOAT _12, 710 FLOAT _21, 711 FLOAT _22, 712 FLOAT _31, 713 FLOAT _32 714 ) 715 { 716 this._11 = _11; 717 this._12 = _12; 718 this._21 = _21; 719 this._22 = _22; 720 this._31 = _31; 721 this._32 = _32; 722 } 723 724 // 725 // Named quasi-constructors 726 // 727 static @property 728 Matrix3x2F 729 Identity() 730 { 731 Matrix3x2F identity; 732 733 identity._11 = 1.0f; 734 identity._12 = 0.0f; 735 identity._21 = 0.0f; 736 identity._22 = 1.0f; 737 identity._31 = 0.0f; 738 identity._32 = 0.0f; 739 740 return identity; 741 } 742 743 static 744 Matrix3x2F 745 Translation( 746 D2D1_SIZE_F size 747 ) 748 { 749 Matrix3x2F translation; 750 751 translation._11 = 1.0; translation._12 = 0.0; 752 translation._21 = 0.0; translation._22 = 1.0; 753 translation._31 = size.width; translation._32 = size.height; 754 755 return translation; 756 } 757 758 static 759 Matrix3x2F 760 Translation( 761 FLOAT x, 762 FLOAT y 763 ) 764 { 765 return Translation(SizeF(x, y)); 766 } 767 768 769 static 770 Matrix3x2F 771 Scale( 772 D2D1_SIZE_F size, 773 D2D1_POINT_2F center = D2D1.Point2F() 774 ) 775 { 776 Matrix3x2F scale; 777 778 scale._11 = size.width; scale._12 = 0.0; 779 scale._21 = 0.0; scale._22 = size.height; 780 scale._31 = center.x - size.width * center.x; 781 scale._32 = center.y - size.height * center.y; 782 783 return scale; 784 } 785 786 static 787 Matrix3x2F 788 Scale( 789 FLOAT x, 790 FLOAT y, 791 D2D1_POINT_2F center = D2D1.Point2F() 792 ) 793 { 794 return Scale(SizeF(x, y), center); 795 } 796 797 static 798 Matrix3x2F 799 Rotation( 800 FLOAT angle, 801 D2D1_POINT_2F center = D2D1.Point2F() 802 ) 803 { 804 Matrix3x2F rotation; 805 806 D2D1MakeRotateMatrix(angle, center, &rotation.matrix); 807 808 return rotation; 809 } 810 811 static 812 Matrix3x2F 813 Skew( 814 FLOAT angleX, 815 FLOAT angleY, 816 D2D1_POINT_2F center = D2D1.Point2F() 817 ) 818 { 819 Matrix3x2F skew; 820 821 D2D1MakeSkewMatrix(angleX, angleY, center, &skew.matrix); 822 823 return skew; 824 } 825 826 //TODO: find a way to do such manipulation 827 /* 828 // 829 // Functions for convertion from the base D2D1_MATRIX_3X2_F to this type 830 // without making a copy 831 // 832 static 833 const(Matrix3x2F)* 834 ReinterpretBaseType(const(D2D1_MATRIX_3X2_F)* pMatrix) 835 { 836 return cast(const(Matrix3x2F)*)pMatrix; 837 } 838 839 static 840 COM_DECLSPEC_NOTHROW 841 inline 842 Matrix3x2F* 843 ReinterpretBaseType(D2D1_MATRIX_3X2_F *pMatrix) 844 { 845 return static_cast<Matrix3x2F *>(pMatrix); 846 } 847 */ 848 849 FLOAT 850 Determinant() const 851 { 852 return (_11 * _22) - (_12 * _21); 853 } 854 855 bool 856 IsInvertible() const 857 { 858 return !!D2D1IsMatrixInvertible(&this.matrix); 859 } 860 861 bool 862 Invert() 863 { 864 return !!D2D1InvertMatrix(&this.matrix); 865 } 866 867 bool 868 IsIdentity() const 869 { 870 return _11 == 1.0f && _12 == 0.0f 871 && _21 == 0.0f && _22 == 1.0f 872 && _31 == 0.0f && _32 == 0.0f; 873 } 874 875 void SetProduct( 876 in Matrix3x2F a, 877 in Matrix3x2F b 878 ) 879 { 880 _11 = a._11 * b._11 + a._12 * b._21; 881 _12 = a._11 * b._12 + a._12 * b._22; 882 _21 = a._21 * b._11 + a._22 * b._21; 883 _22 = a._21 * b._12 + a._22 * b._22; 884 _31 = a._31 * b._11 + a._32 * b._21 + b._31; 885 _32 = a._31 * b._12 + a._32 * b._22 + b._32; 886 } 887 888 Matrix3x2F opBinary(string op)(Matrix3x2F rhs) const 889 { 890 Matrix3x2F result; 891 892 static if (op == "*") 893 result.SetProduct(this,rhs); 894 else 895 static assert(0, "Operator "~op~" not implemented"); 896 897 return result; 898 } 899 900 D2D1_POINT_2F 901 TransformPoint( 902 D2D1_POINT_2F point 903 ) const 904 { 905 D2D1_POINT_2F result = 906 { 907 point.x * _11 + point.y * _21 + _31, 908 point.x * _12 + point.y * _22 + _32 909 }; 910 911 return result; 912 } 913 /* TODO 914 static Matrix3x2F MakeFromBaseType(in D2D1_MATRIX_3X2_F mat) 915 { 916 Matrix3x2F matrix = new Matrix3x2F(mat); 917 return matrix; 918 } 919 */ 920 } 921 922 static IdentityMatrix() 923 { 924 return Matrix3x2F.Identity(); 925 } 926 927 } // namespace D2D1 928 929 D2D1_POINT_2F opBinary(string op)(in D2D1_POINT_2F point, in D2D1_MATRIX_3X2_F matrix) 930 { 931 return D2D1.Matrix3x2F.ReinterpretBaseType(&matrix).TransformPoint(point); 932 } 933 934 /* 935 COM_DECLSPEC_NOTHROW 936 D2D1FORCEINLINE 937 D2D1_MATRIX_3X2_F 938 operator*( 939 const D2D1_MATRIX_3X2_F &matrix1, 940 const D2D1_MATRIX_3X2_F &matrix2 941 ) 942 { 943 return 944 (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix1)) * 945 (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix2)); 946 } 947 948 COM_DECLSPEC_NOTHROW 949 inline 950 bool 951 operator==(const D2D1_SIZE_U &size1, const D2D1_SIZE_U &size2) 952 { 953 return (size1.width == size2.width) && (size1.height == size2.height); 954 } 955 956 COM_DECLSPEC_NOTHROW 957 inline 958 bool 959 operator==(const D2D1_RECT_U &rect1, const D2D1_RECT_U &rect2) 960 { 961 return (rect1.left == rect2.left) && (rect1.top == rect2.top) && 962 (rect1.right == rect2.right) && (rect1.bottom == rect2.bottom); 963 } 964 965 #endif // #ifndef D2D_USE_C_DEFINITIONS 966 967 #endif // #ifndef _D2D1_HELPER_H_ 968 969 */